﻿using gt.rediscachemanager.Entry;
using gt.rediscachemanager.Utility;
using StackExchange.Redis;
using System;
using System.Collections.Generic;
using System.Threading.Tasks;

namespace gt.rediscachemanager.Impl.RedisClient
{
    public partial class RedisClient
    {
        #region String

        /// <summary>
        /// 设置string key-value
        /// </summary>
        public bool StringSet(string key, string value, TimeSpan? expiredTime = null, When when = When.Always, CommandFlags flags = CommandFlags.None)
        {
            var message = new StringSetMessage(key, value, expiredTime, when);
            return Execute(RedisCommand.StringSet, message, flags).BoolResult;
        }
        /// <summary>
        /// append string
        /// 返回 append后 string length
        /// </summary>
        public long StringAppend(string key, string value, TimeSpan? expiredTime = null, CommandFlags flags = CommandFlags.None)
        {
            var message = new StringAppendMessage(key, value);
            var result = Execute(RedisCommand.StringAppend, message, flags).LongResult;
            if (expiredTime != null)
                KeyExpired(key, expiredTime.Value);
            return result;
        }
        /// <summary>
        /// 批量设置string key-value
        /// 集群模式不支持
        /// </summary>
        public bool StringSet(KeyValuePair<string, string>[] keyValues, When when = When.Always, CommandFlags flags = CommandFlags.None)
        {
            if (this.Pool.Mode != PoolMode.Single)
                throw new InvalidOperationException("this operation do not support by cluster mode!");
            if (keyValues == null || keyValues.Length == 0) return false;
            var kvs = RedisValueUtility.Convert(keyValues);
            var message = new StringSetArrayMessage(kvs, when);
            return Execute(RedisCommand.StringSetArray, message, flags).BoolResult;
        }
        /// <summary>
        /// 设置string key-value,并返回旧值
        /// </summary>
        /// <returns></returns>
        public string StringGetSet(string key, string value, TimeSpan? expiredTime = null, CommandFlags flags = CommandFlags.None)
        {
            var message = new StringGetSetMessage(key, value);
            var result = Execute(RedisCommand.StringGetSet, message, flags).RedisValueResult;
            if (expiredTime != null)
                KeyExpired(key, expiredTime.Value);
            return result;
        }
        /// <summary>
        /// 获取string key-value
        /// </summary>
        public string StringGet(string key, CommandFlags flags = CommandFlags.None)
        {
            var message = new StringGetMessage(key);
            return Execute(RedisCommand.StringGet, message, flags).RedisValueResult;
        }
        /// <summary>
        /// 原子性key-value 值增长
        /// </summary>
        public long StringIncrement(string key, TimeSpan? expiredTime = null, long inc = 1, CommandFlags flags = CommandFlags.None)
        {
            var message = new StringIncrementMessage(key, inc);
            long result = Execute(RedisCommand.StringIncrement, message, flags).LongResult;
            if (expiredTime != null)
                KeyExpired(key, expiredTime.Value);
            return result;
        }

        #endregion

        public async Task<bool> StringSetAsync(string key, string value, TimeSpan? expiredTime = null, CommandFlags flags = CommandFlags.None, When when = When.Always)
        {
            var message = new StringSetMessage(key, value, expiredTime, when);
            return await ExecuteAsync(RedisCommand.StringSet, message, flags).ContinueWith(t =>
            {
                return t.Result.BoolResult;
            }).ConfigureAwait(false);
        }

        public async Task<long> StringAppendAsync(string key, string value, TimeSpan? expiredTime = null, CommandFlags flags = CommandFlags.None)
        {
            var message = new StringAppendMessage(key, value);
            return await ExecuteAsync(RedisCommand.StringAppend, message, flags).ContinueWith((task) =>
            {
                var result = task.Result.LongResult;
                if (expiredTime != null)
                    KeyExpired(key, expiredTime.Value);
                return result;
            }).ConfigureAwait(false);
        }

        public async Task<string> StringGetSetAsync(string key, string value, CommandFlags flags = CommandFlags.None)
        {
            var message = new StringGetSetMessage(key, value);
            return await ExecuteAsync(RedisCommand.StringGetSet, message, flags).ContinueWith(t =>
            {
                return t.Result.RedisValueResult;
            }).ConfigureAwait(false);
        }

        public async Task<string> StringGetAsync(string key, CommandFlags flags = CommandFlags.None)
        {
            var message = new StringGetMessage(key);
            return await ExecuteAsync(RedisCommand.StringGet, message, flags).ContinueWith(t =>
            {
                return t.Result.RedisValueResult;
            }).ConfigureAwait(false);
        }

        public async Task<long> StringIncrementAsync(string key, TimeSpan? expiredTime = null, long inc = 1, CommandFlags flags = CommandFlags.None)
        {
            var message = new StringIncrementMessage(key, inc);
            return await ExecuteAsync(RedisCommand.StringIncrement, message, flags).ContinueWith((task) =>
            {
                var result = task.Result.LongResult;
                if (expiredTime != null)
                    KeyExpired(key, expiredTime.Value);
                return result;
            }).ConfigureAwait(false);
        }
    }
}
